import pandas as pd
import numpy as np
from io import StringIO

data = """
对话开始 >>
李庆辉 2020-05-15 12:33:50
    你好，可以退货吗
客服999 2020-05-15 12:33:55 >>
    工号999很高兴为您服务~。
客服999 2020-05-15 12:33:53
    您好
客服999 2020-05-15 12:34:04
    您可以自己操作申请取消订单的。
李庆辉 2020-05-15 12:34:04
    退款多久到账呢？
客服999 2020-05-15 12:34:28
    一般1-7个工作日
李庆辉 2020-05-15 12:35:01
    OMG! 好久呢
李庆辉 2020-05-15 12:40:55
    能不能快点
客服999 2020-05-15 12:42:23
    一般情况下很快就会到账的。
李庆辉 2020-05-15 12:43:04
    OMG! 好久呢
客服999 2020-05-15 12:44:01
    一般情况下很快就会到账的。
对话结束  >>
    长时间未回复，对话结束
"""
# 其中聊天内容前有一个 tab 符，
# 首尾两句是系统自动提示，用“ >> ”标识，
# 客服名称开头有“客服”字样，
# 现在需要知道首次响应时长和平均响应时长。
"""
首先来计算首次响应时长。
首次响应时长指的是用户发出第一句到人工客服回复第一句的时间长度。
为了实现需求，先将数据载入 DataFrame。
由于 data 是字符串，用 StringIO 将字符串读入内存的缓冲区，以便 Pandas 来读取
"""

df = pd.read_csv(StringIO(data), names=["chats"], dtype=str)
print(df)

# 对数据进行整理，剔除系统自动提示内容，提取双方昵称、是否客服、发送时间等字段，以方便计算：

# 排除系统自动提示符和对话内容
tmpdf = df.loc[~(df["chats"].str.endswith(">>")) & ~(df["chats"].str.startswith("    "))]

# 提取双方昵称
tmpdf = tmpdf.assign(name=lambda x: x["chats"].str.split(" ").str[0])

# 判断是否客服（客服昵称中有“客服”字样）
tmpdf = tmpdf.assign(staff=lambda x: x["name"].str.contains("客服"))

# 提取并转换为时间类型
tmpdf = tmpdf.assign(time=lambda x: pd.to_datetime(x["chats"].str[-20:]))

# 按时间先后排期
tmpdf.sort_values("time", inplace=True)
print(tmpdf)

# 接下来获取人工客服回复第一句的时间和用户发出第一句的时间并相减，便得出首次响应时长：
tmpdf = tmpdf.assign(first=lambda x: x[x["staff"] == True]["time"].min() - x[x["staff"] == False]["time"].min())
print("首次响应时长为 %d 秒" % tmpdf.iloc[0, -1].total_seconds())
# print(tmpdf)

"""
接下来计算平均响应时长。
平均响应时长的算法是用户发出信息后（不管接连再发了几条），
客户回应时间（不管接连再发了几条）的间隔，
总是一方一个时间，对这些间隔求平均就得到平均响应时长。
"""

# 开始求平均时长，保留一方连续发言情况中的第一条
# =============================================
tmpdf = tmpdf.loc[lambda x: (x[['name']].shift() != x[['name']]).any(axis=1)]
# print(tmpdf)

# 求先后对话的时间差
tmpdf = tmpdf.assign(diff=lambda x: x["time"].diff())

# 对所有的时间差求平均数，单位为秒
df = tmpdf.assign(avg=lambda x: x["diff"].mean().seconds)
print("平均响应时长为 %d 秒" % df.iloc[0, -1])

"""
思路是，
    将用户名下移后再判断是否还是原用户名，
    如果是则剔除，这样就只保留了一方连续发言时的第一条，
    然后再对上下条消息的发出时间求差值，
    最后再算平均值，单位取秒。
最终结果为 87 秒。
"""
